/**
* @file SFXFilter.cpp
* @author Max Ocklind
* @version 2010-01-11
*
* An abstract class used for implementing sound effect filters.</br>
* The <code>mFilter</code> function should be overriden and contain the actual filtering process.
*/


/* includes */

#include "SFXFilter.h"


/* functions */


/* public */

/**
* Enables the sound effect filter on the specified OpenAL sound source.
*
* @param source the OpenAL sound source to be filtered
*/
void SFXFilter::enable(SoundSource source)
{
	mPushSourceProperties(source);
	mFilter(source);
}

/**
* Disables the sound effect filter on the specified OpenAL sound source.
*
* @param source the OpenAL sound source to remove the filter from
*/
void SFXFilter::disable(SoundSource source)
{
	std::map<SoundSource, SourceProperties>::iterator it = mSourceProperties.find(source);
	if (it != mSourceProperties.end())
	{
		// detach auxiliary sends and filters
		for (int i = 0; i < mEffectSlots.size(); i++)
		{
			alSource3i(source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, i, NULL);
			errCheck->checkALError("SFXFilter", "disable (detach aux sends and filters)");
		}

		mPopSoundProperties(source);
	}
}


/**
SXFFilter* SFXFilter::combineWith(SFXFilter* filter)
{
	throw new string("combine function not yet supported");
}**/


/* private */

/**
* Stores the current basic sound properties of the specified OpenAL sound source.
*
* @param source the OpenAL sound source to store the properties of
*/
void SFXFilter::mPushSourceProperties(SoundSource source)
{
	SourceProperties tmp;

	alGetSourcef(source, AL_PITCH, &(tmp.pitch));
	errCheck->checkALError("SFXFilter", "mPushSourceProperties (pitch)");

	alGetSourcef(source, AL_GAIN, &(tmp.gain));
	errCheck->checkALError("SFXFilter", "mPushSourceProperties (gain)");

	alGetSourcef(source, AL_ROLLOFF_FACTOR, &(tmp.rolloffFactor));
	errCheck->checkALError("SFXFilter", "mPushSourceProperties (rolloff factor)");

	mSourceProperties[source] = tmp;
}

/**
* Restores the saved basic sound properties of the specified OpenAL sound source.
*
* @param source the OpenAL sound source to restore the properties of
*/
void SFXFilter::mPopSoundProperties(SoundSource source)
{
	SourceProperties tmp = mSourceProperties[source];

	alSourcef(source, AL_PITCH, tmp.pitch);
	errCheck->checkALError("SFXFilter", "mPopSourceProperties (pitch)");

	alSourcef(source, AL_GAIN, tmp.gain);
	errCheck->checkALError("SFXFilter", "mPopSourceProperties (gain)");

	alSourcef(source, AL_ROLLOFF_FACTOR, tmp.rolloffFactor);
	errCheck->checkALError("SFXFilter", "mPopSourceProperties (rolloff factor)");

	mSourceProperties.erase(source);
}

/**
* Checks if all the EFX extension function pointers are valid.
*
* @return <code>true</code> if <b>all</b> EFX function pointers are correct, otherwise <code>false</code>
*/
bool SFXFilter::mCheckEFXPointers()
{
	return
		(	alGenEffects
			&& alDeleteEffects
			&& alIsEffect
			&& alEffecti
			&& alEffectiv
			&& alEffectf
			&& alEffectfv
			&& alGetEffecti
			&& alGetEffectiv
			&& alGetEffectf
			&& alGetEffectfv
				
			&& alGenFilters
			&& alDeleteFilters
			&& alIsFilter
			&& alFilteri
			&& alFilteriv
			&& alFilterf
			&& alFilterfv
			&& alGetFilteri
			&& alGetFilteriv
			&& alGetFilterf
			&& alGetFilterfv
				
			&& alGenAuxiliaryEffectSlots
			&& alDeleteAuxiliaryEffectSlots
			&& alIsAuxiliaryEffectSlot
			&& alAuxiliaryEffectSloti
			&& alAuxiliaryEffectSlotiv
			&& alAuxiliaryEffectSlotf
			&& alAuxiliaryEffectSlotfv
			&& alGetAuxiliaryEffectSloti
			&& alGetAuxiliaryEffectSlotiv
			&& alGetAuxiliaryEffectSlotf
			&& alGetAuxiliaryEffectSlotfv
		);
}